// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>

// using namespace std;


// void* threadRoutine(void* args)
// {
//     while (true)
//     {
//         cout << "new thread, pid: " << getpid() << endl; 
//         sleep(2); 
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, nullptr);  

//     while(true)
//     {
//         cout << "main thread, pid: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }


// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>

// using namespace std;

// //show方法可以被多个执行流执行。
// void show(const string& name)
// {
//     cout << name << "say#: " << "hello thread" << endl;
// }

// void* threadRoutine(void* args)
// {
//     while (true)
//     {
//         // cout << "new thread, pid: " << getpid() << endl; 
//         show("[new thread]");
//         sleep(2); 
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, nullptr);  

//     while(true)
//     {
//         // cout << "main thread, pid: " << getpid() << endl;
//         show("[main thread]");
//         sleep(1);
//     }

//     return 0;
// }




// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>

// using namespace std;

// int g_val = 100;


// //show方法可以被多个执行流执行。
// void show(const string& name)
// {
//     cout << name << "say#: " << "hello thread" << endl;
// }

// void* threadRoutine(void* args)
// {
//     while (true)
//     {
//         printf("new thread pid: %d, g_val: %d, &g_val: 0x%p\n", getpid(), g_val, &g_val);

//         sleep(5); 

//         int a = 10;
//         a /= 0;

//         // cout << "new thread, pid: " << getpid() << endl; 
//         // show("[new thread]");
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, nullptr);  

//     while(true)
//     {
//         printf("main thread pid: %d, g_val: %d, &g_val: 0x%p\n", getpid(), g_val, &g_val);
//         // cout << "main thread, pid: " << getpid() << ", g_val: " << g_val << ", &g_val: " << &g_val << endl;
//         // show("[main thread]");
//         sleep(1);
//         g_val++;

//     }


//     return 0;
// }



// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>

// using namespace std;

// int g_val = 100;


// //show方法可以被多个执行流执行。
// void show(const string& name)
// {
//     cout << name << "say#: " << "hello thread" << endl;
// }

// void* threadRoutine(void* args)
// {
//     while (true)
//     {
//         printf("new thread pid: %d, g_val: %d, &g_val: 0x%p\n", getpid(), g_val, &g_val);

//         sleep(1); 


//         // cout << "new thread, pid: " << getpid() << endl; 
//         // show("[new thread]");
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, nullptr);  

//     while(true)
//     {
//         printf("main thread pid: %d, g_val: %d, &g_val: 0x%p, create new thread tid: 0x%p\n", getpid(), g_val, &g_val, tid);
//         // cout << "main thread, pid: " << getpid() << ", g_val: " << g_val << ", &g_val: " << &g_val << endl;
//         // show("[main thread]");
//         sleep(1); 
//         g_val++;

//     }


//     return 0;
// }



// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>

// using namespace std;

// int g_val = 100;


// //show方法可以被多个执行流执行。
// void show(const string& name)
// {
//     cout << name << "say#: " << "hello thread" << endl;
// }

// void* threadRoutine(void* args)
// {
//     const char* name = (const char*)args;
//     while (true)
//     {
//         printf("name: %s, new thread pid: %d, g_val: %d, &g_val: 0x%p\n",name, getpid(), g_val, &g_val);

//         sleep(1); 


//         // cout << "new thread, pid: " << getpid() << endl; 
//         // show("[new thread]");
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, (void*)"Thread 1");  

//     while(true)
//     {
//         printf("main thread pid: %d, g_val: %d, &g_val: 0x%p, create new thread tid: 0x%p\n", getpid(), g_val, &g_val, tid);
//         // cout << "main thread, pid: " << getpid() << ", g_val: " << g_val << ", &g_val: " << &g_val << endl;
//         // show("[main thread]");
//         sleep(1); 
//         g_val++;

//     }
//     return 0;
// }


// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// #include<cstdlib>
// using namespace std;
// int g_val = 100;


// //show方法可以被多个执行流执行。
// void show(const string& name)
// {
//     cout << name << "say#: " << "hello thread" << endl;
// }

// void* threadRoutine(void* args)
// {
//     const char* name = (const char*)args;
//     while (true)
//     {
//         printf("name: %s, new thread pid: %d, g_val: %d, &g_val: 0x%p\n",name, getpid(), g_val, &g_val);

//         sleep(1); 


//         // cout << "new thread, pid: " << getpid() << endl; 
//         // show("[new thread]");
//     }

//     exit(11);  
//     // return nullptr; //走到这里默认就退出了。 
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, (void*)"Thread 1");  

//     sleep(1);
//     pthread_cancel(tid);     

//     // while(true)
//     // {
//     //     printf("main thread pid: %d, g_val: %d, &g_val: 0x%p, create new thread tid: 0x%p\n", getpid(), g_val, &g_val, tid);
//     //     // cout << "main thread, pid: " << getpid() << ", g_val: " << g_val << ", &g_val: " << &g_val << endl;
//     //     // show("[main thread]");
//     //     sleep(1); 
//     //     g_val++;

//     // }
//     void* retval;
//     pthread_join(tid, &retval);   //main thread等待的时候， 默认是阻塞等待的。  为什么我们这里不考虑异常呢？ 做不到！！ 
//     cout << "main thread quit ...ret: " << (long long int)retval << endl;
//     return 0;
// }

// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// #include<cstdlib>
// using namespace std;

// class Request
// {
// public:
//     Request(int start, int end, const string& threadname)
//         :_start(start)
//         ,_end(end)
//         ,_threadname(threadname)
//     {}

// public:
//     int _start;
//     int _end;
//     string _threadname;

// };


// class Response
// {
// public:
//     Response(int result, int exitcode)
//         :_result(result)
//         ,_exitcode(exitcode)
//     {}
// public:
//     int _result;
//     int _exitcode;
// };


// void* sumCount(void* args)
// {
//     Request* rq = static_cast<Request*>(args);
//     Response* rsp = new Response(0, 0); 

//     for (int i = rq->_start; i <= rq->_end; i++)
//     {
//         cout << rq->_threadname << " is running, caling..., " << i << endl;
//         rsp->_result += i;
//         usleep(100000);
//     }
//     return rsp; 
// }

// int main()
// {
//     pthread_t tid;
//     Request *rq = new Request(1, 100, "thread 1");
//     pthread_create(&tid, nullptr, sumCount, rq);


//     void* ret;
//     pthread_join(tid, &ret);
//     Response* rsp = static_cast<Response*>(ret);

//     cout << "rsp->result: " << rsp->_result << ", exitcode: " << rsp->_exitcode << endl; 
//     return 0;
// }


// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// #include<cstdlib>
// using namespace std;

// #include<thread>

// void threadrun()
// {
//     while (true)
//     {
//         cout << "I am a new thead for C++" << endl;
//         sleep(1);
//     }
// }
 
// int main()
// {
//     std::thread t1(threadrun);

//     t1.join();
//     return 0;
// }

// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// #include<cstdlib>
// using namespace std;

// std::string toHex(pthread_t tid)
// {
//     char hex[64];
//     snprintf(hex, sizeof(hex), "%p", tid);
//     return hex;
// }

// void* threadRoutine(void* args)
// {
//     while (true)
//     {
//         cout << "thread id: " << toHex(pthread_self()) << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, (void*)"thread 1");

//     cout << "main thread create thread done, new thread id: " << toHex(tid) << endl;
//     pthread_join(tid, nullptr); 
//     return 0;
// }

// #include<iostream>
// #include<unistd.h>
// #include<pthread.h>
// #include<cstdlib>
// using namespace std;

// void* threadRuntine(void* args)
// {
//     string name = static_cast<char*>(args);
//     int cnt = 5;
//     while (cnt--)
//     {
//         cout << args << " say#: " << "I am a new thread" << endl;
//         sleep(1);
//     }
//     pthread_exit((void*)1);
// }


// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRuntine, (void*)"thread 1");

//     sleep(2);
//     pthread_cancel(tid);

//     void* ret;
//     pthread_join(tid, &ret);
//     cout << (long long int)ret << endl;
//     return 0;
// }


// #include<iostream>
// #include<unistd.h>
// #include<string>
// #include<cstdlib>
// #include<pthread.h>
// using namespace std;


// class Request
// {
// public:
//     Request(int start, int end, string threadname)
//         :_start(start)
//         ,_end(end)
//         ,_threadname(threadname)
//     {}

// public:
//     int _start;
//     int _end;
//     string _threadname;
// };


// class Response
// {
// public:
//     Response(int result, int exitcode)
//         :_result(result)
//         ,_exitcode(exitcode)
//     {}

// public:
//     int _result;
//     int _exitcode;
// };

// void* threadRuntine(void* args)
// {
//     Response* rsp = new Response(0, 0);
//     Request* req = static_cast<Request*>(args);
//     for (int i = req->_start; i <= req->_end; i++)
//     {
//         rsp->_result += i;
//         usleep(100000);
//         cout << ".exe is running..." << i << endl;
//     }
//     return (void*)rsp;
// }

// int main()
// {
//     Request* req = new Request(1, 100, "thread 1");
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRuntine, (void*)req);

//     void* ret;

//     pthread_join(tid, &ret);
//     cout << "result: " << static_cast<Response*>(ret)->_result << endl;

//     return 0;
// }


#include<iostream>
using namespace std;
#include<pthread.h>
#include<vector>
#include<unistd.h>

#define NUM 5

using namespace std;

int* p = NULL;

struct threadData
{
    string  threadname;
};

string toHex(pthread_t tid)
{
    char buffer[128];
    snprintf(buffer, sizeof(buffer), "0x%x", tid);
    return buffer;
}


void InitthreadData(threadData* td, int number)
{
    td->threadname = "thread" + to_string(number);   
}

//所有的线程，执行的都是这个函数。 
void* threadRuntine(void* args)
{
    threadData* td = static_cast<threadData*>(args);
    int test_i = 0;
    if (td->threadname == "thread-2") p = &test_i;
    int i = 0;
    while (i < 5)
    {
        cout << "pid: " << getpid() << ", tid: " 
                << toHex(pthread_self()) << ", threadname: " << td->threadname 
                    << "test_i: " << test_i << "&test_t: " << &test_i << endl;
        i++;
        test_i++;
        sleep(2);
    }

    sleep(1);
    cout << "main thread get a thread local value, val: " << *p << ", &val: " << p << endl;
    delete td;  
    return nullptr;
}

int main()
{   
    vector<pthread_t> tids;
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        threadData* td = new threadData;
        InitthreadData(td, i);

        pthread_create(&tid, nullptr, threadRuntine, td);
        tids.push_back(tid);    
        sleep(2);
    }


    for (int i = 0; i < tids.size(); i++)
    {
        pthread_join(tids[i], nullptr); 
    }


    return 0;
}